package spring.cloud.service.task.controller;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import spring.cloud.service.task.dto.TaskDto;
import spring.cloud.service.task.service.TaskService;
import spring.cloud.service.task.utils.PageInfo;
import spring.cloud.service.task.utils.Result;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
@RequestMapping("/task")
@RestController
public class TaskController {
    @Resource
    private TaskService taskService;

    /**
     * page: 1
     * limit: 10
     */
    @GetMapping(value = "/getTaskList")
    public Result getTaskList(@RequestParam(required = false) String namespaceKey, //
                              @RequestParam(required = false) String description, //
                              @RequestParam(required = false) String status, //
                              @RequestParam(required = false) Integer page, //
                              @RequestParam(required = false) Integer limit) throws RuntimeException {
        Result result = new Result();
        result.setCode(Result.table_query_success_code);
        result.setMsg(Result.table_query_success_msg);
        status = StringUtils.trimToNull(status);//下拉框""为空BUG fix
        PageInfo pageInfo = taskService.getTaskList(namespaceKey, description, status, page, limit);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("total", pageInfo.getTotalCount());
        map.put("records", pageInfo.getRecords());
        result.setData(map);
        return result;
    }

    @PostMapping(value = "/addTask")
    public Result addTask(@RequestBody String data) throws RuntimeException {
        JSONObject jsonObject = JSON.parseObject(data);
        TaskDto taskDto = TaskDto.parse(jsonObject);
        String userId = "CXL";
        taskDto.setCreateBy(userId);
        taskDto.setCreateTime(new Date());
        taskDto.setLastUpdateBy(userId);
        taskDto.setLastUpdateTime(new Date());
        synchronized (taskDto.getNamespaceKey().intern()) {
            try {
                return taskService.addTask(taskDto);
            } catch (Exception e) {
                log.error(ExceptionUtils.getStackTrace(e));
                Result result = Result.fail("添加任务失败:" + e.getMessage());
                return result;

            }

        }
    }

    @PostMapping(value = "/updateTask")
    public Result updateTask(@RequestBody String data) throws RuntimeException {
        JSONObject jsonObject = JSON.parseObject(data);
        TaskDto taskDto = TaskDto.parse(jsonObject);
        String userId = "CXL";
        taskDto.setLastUpdateBy(userId);
        taskDto.setLastUpdateTime(new Date());
        synchronized (taskDto.getNamespaceKey().intern()) {
            try {
                return taskService.updateTask(taskDto);
            } catch (Exception e) {
                Result result = Result.fail("修改任务失败:" + e.getMessage());
                return result;
            }
        }
    }

    @PostMapping(value = "/deleteTask")
    public Result deleteTask(@RequestParam(name = "namespaceKey") String namespaceKey, @RequestParam(name = "taskId") String taskId) throws RuntimeException {
        TaskDto taskDto = new TaskDto();
        taskDto.setLastUpdateBy("CXL");
        taskDto.setLastUpdateTime(new Date());
        try {
            Result result = taskService.deleteTask(taskDto);
            return result;
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            return Result.fail("删除任务失败");
        }
    }

    @PostMapping(value = "/updateTaskStatus")
    public Result updateTaskStatus(@RequestBody String data) throws RuntimeException {
        JSONObject jsonObject = JSON.parseObject(data);
        String zooKeeperKey = jsonObject.getString("zooKeeperKey");
        String status = jsonObject.getString("status");
        Result result = Result.success();// taskService.updateTaskStatus(zooKeeperKey, status);
        return result;
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 获取域下所有任务的名字
     *
     * @param nameSpace 域名
     * @return 全域任务名字
     */
    @RequestMapping(value = "/getTaskIdList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result getTaskIdList(@PathVariable String nameSpace) throws RuntimeException {
        return Result.success(taskService.getTaskIdList(nameSpace));
    }

    @RequestMapping(value = "/task2/enableTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result enableTask(final HttpServletRequest request,
                             @PathVariable String nameSpace,
                             @PathVariable String taskId) throws RuntimeException {
        taskService.enableTask(nameSpace, taskId, "");
        return new Result();
    }

    @RequestMapping(value = "/task2/batchEnableTaskList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result batchEnableTaskList(final HttpServletRequest request,
                                      @PathVariable String nameSpace,
                                      @RequestParam List<String> taskIds) throws RuntimeException {
        for (String taskId : taskIds) {
            taskService.enableTask(nameSpace, taskId, "");
        }
        return new Result();
    }

    @RequestMapping(value = "/task2/disableTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result disableTask(final HttpServletRequest request,
                              @PathVariable String nameSpace,
                              @PathVariable String taskId) throws RuntimeException {
        taskService.disableTask(nameSpace, taskId, "");
        return new Result();
    }


    @RequestMapping(value = "/task2/batchDeleteDisableTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result disableTask(final HttpServletRequest request,
                              @PathVariable String nameSpace,
                              @RequestParam List<String> taskIds) throws RuntimeException {
        for (String taskId : taskIds) {
            taskService.disableTask(nameSpace, taskId, "");
        }
        return new Result();
    }

    @RequestMapping(value = "/task2/deleteTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result deleteTask(final HttpServletRequest request,
                             @PathVariable String nameSpace,
                             @PathVariable String taskId) throws RuntimeException {
        TaskDto taskDto = new TaskDto();
        taskDto.setNamespaceKey(nameSpace);
        taskDto.setTaskId(taskId);
        taskDto.setLastUpdateBy("");
        taskService.deleteTask(taskDto);
        return new Result();
    }

    @RequestMapping(value = "/task2/batchDeleteTask", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result batchDeleteTask(final HttpServletRequest request,
                                  @PathVariable String nameSpace,
                                  @RequestParam List<String> taskIds) throws RuntimeException {

        List<String> successtaskIds = new ArrayList<>();
        List<String> failtaskIds = new ArrayList<>();
        for (String taskId : taskIds) {
            try {
                TaskDto taskDto = new TaskDto();
                taskDto.setNamespaceKey(nameSpace);
                taskDto.setTaskId(taskId);
                taskDto.setLastUpdateBy("");
                taskService.deleteTask(taskDto);
                successtaskIds.add(taskId);
            } catch (Exception e) {
                failtaskIds.add(taskId);
                log.info("remove job failed", e);
            }
        }
        if (!failtaskIds.isEmpty()) {
            StringBuilder message = new StringBuilder();
            message.append("删除成功的任务:").append(successtaskIds).append("，").append("删除失败的任务:").append(failtaskIds);
            throw new RuntimeException(message.toString());
        }
        return new Result();
    }

    /**
     * 批量设置任务的优先Executor
     */
    @RequestMapping(value = "/task2/batchSetPreferExecutorIdList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result batchSetPreferExecutorIdList(final HttpServletRequest request,
                                               @PathVariable String nameSpace,
                                               @RequestParam List<String> taskIds,
                                               @RequestParam String preferList) throws RuntimeException {
        for (String taskId : taskIds) {
            taskService.setPreferExecutorIdList(nameSpace, taskId, preferList);
        }
        return new Result();
    }

    /**
     * 获取该任务可选择的优先Executor
     */
    @RequestMapping(value = "/task2/getExecutorList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result getExecutors(final HttpServletRequest request, @PathVariable String nameSpace,
                               @PathVariable String taskId) throws RuntimeException {
        return Result.success(taskService.getExecutorList(nameSpace, taskId));
    }

    @RequestMapping(value = "/task2/stopAtOnce", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result stopAtOnce(@PathVariable String nameSpace,
                             @PathVariable String taskId) throws RuntimeException {
        final JSONObject triggeredData = new JSONObject();
        taskService.stopTaskInstanceId(nameSpace, taskId, null, triggeredData);
        return new Result();
    }


    @RequestMapping(value = "/task2/runAtOnce", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result runAtOnce(@PathVariable String nameSpace,
                            @PathVariable String taskId) throws RuntimeException {
        final JSONObject triggeredData = new JSONObject();
        taskService.rerunTaskInstanceId(nameSpace, taskId, null, triggeredData);
        return new Result();
    }


    @RequestMapping(value = "/task2/getTaskDtoList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Object> getTaskConfigurationList(@PathVariable("nameSpace") String nameSpace) throws RuntimeException {
        HttpHeaders httpHeaders = new HttpHeaders();
        try {
            List<TaskDto> taskDtoList = taskService.getTaskDtoList(nameSpace);
            return new ResponseEntity<Object>(taskDtoList, httpHeaders, HttpStatus.OK);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @RequestMapping(value = "/getRestAPIJobInfo", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Object> query(@PathVariable("nameSpace") String nameSpace,
                                        @PathVariable("taskId") String taskId) throws RuntimeException {
        HttpHeaders httpHeaders = new HttpHeaders();
        try {
            TaskDto taskConfiguration = taskService.getTaskInfo(nameSpace, taskId);
            return new ResponseEntity<Object>(taskConfiguration, httpHeaders, HttpStatus.OK);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }


    @RequestMapping(value = "/getTaskInfoList2", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Object> queryAll(@PathVariable("nameSpace") String nameSpace)
            throws RuntimeException {
        HttpHeaders httpHeaders = new HttpHeaders();
        try {
            List<TaskDto> apiJobInfos = taskService.getTaskInfoList(nameSpace);
            return new ResponseEntity<Object>(apiJobInfos, httpHeaders, HttpStatus.OK);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 获取任务执行状态
     */
    @RequestMapping(value = "/task2/getTaskItemExecuteInfoList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result getExecutionStatus(final HttpServletRequest request, @PathVariable String nameSpace, @PathVariable String taskId) throws Exception {
        return Result.success(taskService.getTaskItemExecuteInfoList(nameSpace, taskId));
    }

    /**
     * 获取任务执行状态
     */
    @RequestMapping(value = "/task2/getTaskExecutorStatusInfoList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @GetMapping(value = "/getTaskExecutorStatusInfoList")
    public Result getTaskExecutorStatusList(final HttpServletRequest request, @PathVariable String nameSpace, @PathVariable String taskId) throws RuntimeException {
        return Result.success(taskService.getTaskExecutorStatusInfoList(nameSpace, taskId));
    }

    /**
     * 获取任务执行状态
     */
    @RequestMapping(value = "/task2/getTaskExecutorList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result getTaskExecutorList(final HttpServletRequest request, @PathVariable String nameSpace, @PathVariable String taskId) throws RuntimeException {
        return Result.success(taskService.getTaskExecutorList(nameSpace, taskId));
    }
}
